package service

import (
	"context"
	"encoding/json"
	"qld2devservice/models"
	"qld2devservice/proto"
	"qld2devservice/utils"
	"strconv"

	"google.golang.org/grpc"
)

const (
	ADDRESS_ORDER = "qld2chargeorder:8302"
)

// 1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
func stateFinishOrder(snNum string, finishType int64, finishMsg string) {
	if err := RedisSave(snNum+"/operateFlag", ""); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:redis保存operateFlag失败"))
		return
	}
	defer func() {
		if err := RedisDel(snNum + "/operateFlag"); err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder: redis删除operateFlag失败"))
		}
	}()
	orderSn, err := SpecialOrderSnGet(snNum+"/orderSn", "")
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:1，orderSn获取失败"))
		return
	}
	//amountStr, err := RedisGet(snNum+"/amount", "0")
	//if err != nil {
	//	utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:2，amountStr获取失败"))
	//	return
	//}
	//amount, err := strconv.ParseInt(amountStr, 10, 64)
	//if err != nil {
	//	utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:3，amount转换失败"))
	//	return
	//}
	duration, err := AnalyzeDevDurationGet(snNum + "/openTime")
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:4，duration获取失败"))
		return
	}
	electricity, err := AnalyzeDevPowerElectricityGet(snNum)
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:5，electricity获取失败"))
	}
	//amountRecord, err := CalculateAmountRecord(snNum)
	//if err != nil {
	//	utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:10，活动订单sn失败"))
	//	return
	//}
	amount, amountRecord, err := CalculateAmountType(snNum)
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "CalculateAmountType失败"))
		return
	}

	timetype, err := RedisGet(snNum+"/timeType", "0")
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:10，timeType获取失败"))
	}
	if timetype == "2" {
		qldOutletControlJsonStr, err := RedisGet(snNum+"/control", "{}")
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "获取控制策略失败"))
		}
		var control models.QldOutletControlJson
		err = json.Unmarshal([]byte(qldOutletControlJsonStr), &control)
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "控制策略解析失败"))
		}
		var temp int64
		for i := 0; i < len(control.StepPrice); i++ {
			if electricity < control.StepPrice[i].Elec {
				temp = control.StepPrice[i].Price
				break
			}
		}

		if amount >= temp {
			amount = temp
		}
		if temp <= 0 {
			amount = control.Money
		}
		amountRecord, err = CreateAmountRecord(snNum, strconv.FormatFloat(electricity, 'f', 3, 64), amount)
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "生成消费记录失败"))
		}
	}

	retCode, errMsg, orderId := AutoFinishChargerOrder(snNum, orderSn, amount, duration, finishType, electricity, amountRecord, finishMsg)
	b, err := json.Marshal(map[string]interface{}{
		"retCode": retCode,
		"errMsg":  errMsg,
		"orderId": orderId,
	})
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:6，json字符串转换获取失败"))
	}
	if err := models.SetQldOutletValue(snNum, 0, 0); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:10,更新数据库失败"))
	}
	if err = MqttNoticeSend(snNum+"/orderFinish", string(b)); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
	}

	if err = RedisSave(snNum+"/isWorking", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:11,isWorking保存到etcd失败"))
	}
	if err = MqttNoticeSend(snNum+"/isWorking", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:isWorking推送失败"))
	}
	userIdStr, err := RedisGet(snNum+"/userId", "0")
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:9，orderSn获取失败"))
	}
	if err = RedisDel(snNum + "/userId"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:12,etcd删除userId失败"))
	}
	if userId, err := strconv.ParseInt(userIdStr, 10, 64); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:userId转换获取失败"))
	} else if err = DelUserIdAndSnNum(userId, snNum); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:13,etcd删除userId_snNum失败"))
	}
	if err = RedisSave(snNum+"/electricity", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder: 12，electricity清零etcd失败"))
	}
	if err = MqttNoticeSend(snNum+"/electricity", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
	}
	if err = RedisSave(snNum+"/power", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder: 13，power清零etcd失败"))
	}
	if err = MqttNoticeSend(snNum+"/power", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
	}
	if err = RedisSave(snNum+"/voltage", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder: 14，voltage清零etcd失败"))
	}
	if err = MqttNoticeSend(snNum+"/voltage", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
	}
	if err = RedisSave(snNum+"/current", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder: 15，current清零etcd失败"))
	}
	if err = MqttNoticeSend(snNum+"/current", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
	}
	if err = RedisSave(snNum+"/amount", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder: 16，amount清零etcd失败"))
	}
	if err = MqttNoticeSend(snNum+"/amount", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
	}
	if err = RedisSave(snNum+"/remainAmount", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder: 17，remainAmount清零etcd失败"))
	}
	if err = MqttNoticeSend(snNum+"/remainAmount", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
	}
	if err = RedisSave(snNum+"/soc", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder: 18，soc清零etcd失败"))
	}
	if err = MqttNoticeSend(snNum+"/soc", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
	}
	if err = RedisSave(snNum+"/dSoc", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder: 19，dSoc清零etcd失败"))
	}
	if err = MqttNoticeSend(snNum+"/dSoc", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
	}
	if err = RedisSave(snNum+"/timeLeft", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder: 20，timeLeft清零etcd失败"))
	}
	if err = MqttNoticeSend(snNum+"/timeLeft", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
	}
	if err = RedisSave(snNum+"/restart", ""); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder: 20，restart清零etcd失败"))
	}
	if err = RedisSave(snNum+"/stepelec", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder: 20，stepelec清零etcd失败"))
	}
	if err = RedisSave(snNum+"/duration", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder: 20，duration清零etcd失败"))
	}

}

// 1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
func powerFinishOrder(snNum string, finishType, amount, duration int64, electricity float64, amountRecord string) {
	if err := RedisSave(snNum+"/operateFlag", ""); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder:redis保存operateFlag失败"))
		return
	}
	defer func() {
		if err := RedisDel(snNum + "/operateFlag"); err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder: redis删除operateFlag失败"))
		}
	}()
	orderSn, err := SpecialOrderSnGet(snNum+"/orderSn", "")
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder:1，orderSn获取失败"))
		return
	}
	retCode, errMsg, orderId := AutoFinishChargerOrder(snNum, orderSn, amount, duration, finishType, electricity, amountRecord, "")
	b, err := json.Marshal(map[string]interface{}{
		"retCode": retCode,
		"errMsg":  errMsg,
		"orderId": orderId,
	})
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder:6，json字符串转换获取失败"))
	}
	if err := models.SetQldOutletValue(snNum, 0, 0); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder:10,更新数据库失败"))
	}
	if err = MqttNoticeSend(snNum+"/orderFinish", string(b)); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder:7,orderFinish信息推送失败"))
	}

	userIdStr, err := RedisGet(snNum+"/userId", "0")
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder:9，orderSn获取失败"))
	}
	if err = RedisDel(snNum + "/userId"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder:12,etcd删除userId失败"))
	}

	if userId, err := strconv.ParseInt(userIdStr, 10, 64); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:userId转换获取失败"))
	} else if err = DelUserIdAndSnNum(userId, snNum); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder:13,etcd删除userId_snNum失败"))
	}
	if err = RedisSave(snNum+"/electricity", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder: 12，electricity清零etcd失败"))
	}
	if err = MqttNoticeSend(snNum+"/electricity", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
	}
	if err = RedisSave(snNum+"/power", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder: 13，power清零etcd失败"))
	}
	if err = MqttNoticeSend(snNum+"/power", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
	}
	//if err = RedisSave(snNum+"/maxPower", "0"); err != nil {
	//	utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder: 13，power清零etcd失败"))
	//}
	if err = RedisSave(snNum+"/voltage", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder: 14，voltage清零etcd失败"))
	}
	if err = MqttNoticeSend(snNum+"/voltage", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
	}
	if err = RedisSave(snNum+"/current", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder: 15，current清零etcd失败"))
	}
	if err = MqttNoticeSend(snNum+"/current", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
	}
	if err = RedisSave(snNum+"/amount", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder: 16，amount清零etcd失败"))
	}
	if err = MqttNoticeSend(snNum+"/amount", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
	}
	//if err = RedisSave(snNum+"/remainAmount", "0"); err != nil {
	//	utils.MyPrint(utils.PRINT_ERROR , utils.WrapError(err, "powerFinishOrder: 17，remainAmount清零etcd失败"))
	//}
	if err = RedisSave(snNum+"/soc", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder: 18，soc清零etcd失败"))
	}
	if err = MqttNoticeSend(snNum+"/soc", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
	}
	if err = RedisSave(snNum+"/dSoc", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder: 19，dSoc清零etcd失败"))
	}
	if err = MqttNoticeSend(snNum+"/dSoc", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
	}
	if err = RedisSave(snNum+"/timeLeft", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder: 20，timeLeft清零etcd失败"))
	}
	if err = MqttNoticeSend(snNum+"/timeLeft", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder:7,orderFinish信息推送失败"))
	}
	if err = RedisSave(snNum+"/timeType", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder: 19，timeType保存到redis失败"))
	}
	if err = RedisSave(snNum+"/isWorking", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder:11,isWorking保存到etcd失败"))
	}
	if err = MqttNoticeSend(snNum+"/isWorking", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder:isWorking信息推送失败"))
	}
	// add new
	if err = RedisSave(snNum+"/restart", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder:12,etcd删除restart失败"))
	}
	if err = RedisSave(snNum+"/stoptime", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder:12,etcd删除stoptime失败"))
	}
	if err = RedisSave(snNum+"/stepelec", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder:12,etcd删除ustepelec失败"))
	}
	if err = RedisSave(snNum+"/duration", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "powerFinishOrder:12,etcd删除duration失败"))
	}

}

func AutoFinishChargerOrder(snNum, orderSn string, amount, duration, finishType int64, electricity float64, amountRecord, finishMsg string) (retCode int64, errMsg string, orderId int64) {
	if openByCard, err := RedisGet(snNum+"/openByCard", ""); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "checkState:1，etcd数据isWorking获取失败"))
	} else if openByCard == "openByCard" {
		return AutoFinishChargerOrderCard(snNum, orderSn, amount, duration, finishType, electricity, amountRecord)
	}
	return AutoFinishChargerOrderNormal(snNum, orderSn, amount, duration, finishType, electricity, amountRecord, finishMsg)
}

func AutoFinishChargerOrderNormal(snNum, orderSn string, amount, duration, finishType int64, electricity float64, amountRecord, finishMsg string) (retCode int64, errMsg string, orderId int64) {
	// 连接到 gRPC 服务器
	conn, err := grpc.Dial(ADDRESS_ORDER, grpc.WithInsecure())
	if err != nil {
		errNew := utils.WrapError(err, "AutoFinishChargerOrder,gRPC服务器连接失败")
		utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
		return 301, errNew.Error() + errNew.Msg(), 0
	}
	defer conn.Close()

	// 初始化 gRPC 客户端
	client := proto.NewOutletStatusListenerClient(conn)
	res := &proto.AutoFinishChargerOrderRequest{
		SnNum:        snNum,
		OrderSn:      orderSn,
		Amount:       amount,
		Electricity:  float32(electricity),
		Duration:     duration,
		FinishType:   finishType,
		AmountRecord: amountRecord,
		FinishMsg:    finishMsg,
	}
	utils.MyPrint(utils.PRINT_INFO, "AutoFinishChargerOrderNormal request", res)
	resp, err := client.AutoFinishChargerOrder(context.Background(), res)
	if err != nil {
		errNew := utils.WrapError(err, "AutoFinishChargerOrder的gRPC调用失败")
		utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
		return 302, errNew.Error() + errNew.Msg(), 0
	}
	utils.MyPrint(utils.PRINT_INFO, "AutoFinishChargerOrderNormal response", utils.TransProtoToJson(resp))
	utils.MyPrint(utils.PRINT_INFO, "AutoFinishChargerOrderNormal msg", resp.ErrMsg)
	return int64(resp.RetCode), resp.ErrMsg, resp.OrderId
}

func AutoFinishChargerOrderCard(snNum, orderSn string, amount, duration, finishType int64, electricity float64, amountRecord string) (retCode int64, errMsg string, orderId int64) {
	// 连接到 gRPC 服务器
	conn, err := grpc.Dial(ADDRESS_CARD, grpc.WithInsecure())
	if err != nil {
		errNew := utils.WrapError(err, "AutoFinishChargerOrderCard,gRPC服务器连接失败")
		utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
		return 301, errNew.Error() + errNew.Msg(), 0
	}
	defer conn.Close()

	// 初始化 gRPC 客户端
	client := proto.NewCardInfoServiceClient(conn)
	res := &proto.AutoStopDevRequest{
		SnNum:        snNum,
		OrderSn:      orderSn,
		Amount:       amount,
		Electricity:  float32(electricity),
		Duration:     duration,
		FinishType:   finishType,
		AmountRecord: amountRecord,
	}
	utils.MyPrint(utils.PRINT_INFO, "AutoFinishChargerOrderCard request", res)
	resp, err := client.AutoStopDev(context.Background(), res)
	if err != nil {
		errNew := utils.WrapError(err, "AutoFinishChargerOrderCard的gRPC调用失败")
		utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
		return 302, errNew.Error() + errNew.Msg(), 0
	}
	utils.MyPrint(utils.PRINT_INFO, "AutoFinishChargerOrderCard response", utils.TransProtoToJson(resp))
	utils.MyPrint(utils.PRINT_INFO, "AutoFinishChargerOrderCard msg", resp.ErrMsg)
	if err = RedisDel(snNum + "/openByCard"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "OutLetOpen: 0，opening设置etcd失败"))
	}
	return int64(resp.RetCode), resp.ErrMsg, resp.OrderId
}

func SpecialOrderSnGet(key, defaultValue string) (orderSn string, err error) {
	var err1 error
	orderSn, err1 = RedisGet(key, defaultValue)
	if err1 != nil {
		err = utils.WrapError(err1, "specialOrderSnGet:orderSn获取失败")
		utils.MyPrint(utils.PRINT_ERROR, err.Error())
		return
	}
	if len(orderSn) > 0 {
		if err2 := RedisSave(key, orderSn); err2 != nil {
			err = utils.WrapError(err2, "specialOrderSnGet:orderSn保存redis失败")
			utils.MyPrint(utils.PRINT_ERROR, err.Error())
			return
		}
	} else {
		if orderSn, err1 = RedisGet(key, defaultValue); err1 != nil {
			err = utils.WrapError(err1, "specialOrderSnGet:redis读取orderSn失败")
			utils.MyPrint(utils.PRINT_ERROR, err.Error())
			return
		}
	}
	return
}
